from time import gmtime, strftime

from MarketData.account import Account
from Strategy.config import CONFIG
from MarketData.const import CONST
from PlaceOrder.order import newOrder
from GUI.output import output, PATH


def Account_std(platform, type):
    account = dict()

    for platf in platform:
        account[platf] = Account(platf, type)

        # standardize currency name
        for cur in CONST.CurrencyList:
            cur_platf = account[platf].get_currency(cur)
            if cur_platf in account[platf].balance:
                balance_float = float(account[platf].balance[cur_platf])
                del account[platf].balance[cur_platf]
                account[platf].balance[cur] = balance_float
            else:
                account[platf].balance[cur] = 0.0

    return account


def newOrder_tieAccount(platform, currency, symbol, order, account, account_ini):
    sum_commodity = 0
    sum_commodity_ini = 0
    platf_order = platform[0]

    for platf in platform:
        sum_commodity += account[platf].balance[currency[0]]
        sum_commodity_ini += account_ini[platf].balance[currency[0]]
        if account[platf].balance[currency[0]] < account[platf_order].balance[currency[0]]:
            platf_order = platf

    order_new = list()

    sum_commodity = 10000
    sum_commodity_ini = 5000

    if abs(sum_commodity-sum_commodity_ini) > CONFIG.limit_quantity or abs(sum_commodity/sum_commodity_ini - 1) > 0.1:
        print("WARNING: ASYMETRIC ACCOUNT AND HUGE GAP.")
        return order_new

    if sum_commodity/sum_commodity_ini - 1 > CONFIG.TS_tieBlance:
        amount = min(CONFIG.limit_quantity, sum_commodity-sum_commodity_ini)
        order_new.append({'platform':platf_order, 
                          'symbol':symbol[currency[0], currency[1], platf_order], 
                          'type':"sell", 
                          'order':order["market", platf_order], 
                          'quantity':amount, 
                          'price':0})
    elif sum_commodity_ini/sum_commodity - 1 > CONFIG.TS_tieBlance:
        amount = min(CONFIG.limit_quantity, sum_commodity_ini-sum_commodity)
        order_new.append({'platform':platf_order, 
                          'symbol':symbol[currency[0], currency[1], platf_order], 
                          'type':"buy", 
                          'order':order["market", platf_order], 
                          'quantity':amount, 
                          'price':0})

    return order_new


def update_Account_fromOrder(currency, perct_slippage, 
                             order, account):
    for element in order:
        if element['type'] == "buy":
            account[element['platform']].balance[element['commodity_cur']] += element['quantity'] * (1-CONST.fee[element['platform']])
            account[element['platform']].balance[element['base_cur']] -= element['quantity'] * element['price'] * (1+perct_slippage)
        elif element['type'] == "sell":
            account[element['platform']].balance[element['commodity_cur']] -= element['quantity']
            account[element['platform']].balance[element['base_cur']] += element['quantity'] * element['price'] * (1-CONST.fee[element['platform']]) * (1-perct_slippage)


def tieAccount_trade(platform, currency, symbol, order, perct_slippage, account, account_ini):
    order_TieAccount = newOrder_tieAccount(platform, currency, symbol, order, account, account_ini)
    if order_TieAccount:
        for element in order_TieAccount:
            response_tieAccount = newOrder(element['platform'], element['symbol'], element['type'], element['order'], "%.2f" % element['quantity'], str(element['price'])).result
            output(PATH.ROOTFOLDER + currency[0] + currency[1] + '/response_tieAccount ' + strftime("%Y%m%d", gmtime()) + '.txt', response_tieAccount)
            print(response_tieAccount)

        update_Account_fromOrder(currency, perct_slippage, order_TieAccount, account)

        print("Account Tied, from trade.")


def platf_minmaxCur(platform, cur, account):
    platf_min = platform[0]
    platf_max = platform[0]
    for platf in platform:
        if account[platf].balance[cur] < account[platf_min].balance[cur]:
            platf_min = platf
        if account[platf].balance[cur] > account[platf_max].balance[cur]:
            platf_max = platf

    return (platf_min, platf_max)


def tieAccount_withdraw(platform, currency, account):
    for cur in currency:
        (platf_min, platf_max) = platf_minmaxCur(platform, cur, account)
        balance_max = account[platf_max].balance[cur]
        balance_min = account[platf_min].balance[cur]

        if balance_max/balance_min > 9:
            amount_withdraw = (balance_max - balance_min)/2.0
            withdraw(platf_max, cur, amount_withdraw, wallet_address[platf_min])

            #withdraw only reflected in dedcution immediately. Increase is reflected only when update account.
            account[platf_max].balance[cur] -= amount_withdraw

            print("Account Tied, from withdraw.")